home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / resc.zip / RESCONV / RESCONV.C < prev    next >
C/C++ Source or Header  |  1992-07-13  |  68KB  |  2,295 lines

  1. /*
  2.  *
  3.  *  WinRes - OS/2 to Windows resource conversion utility
  4.  *
  5.  *  RESCONV is a utility program used to convert OS/2 resources to
  6.  *  Windows resources.
  7.  *
  8.  */
  9.  
  10. #include "resconv.h"
  11. #include "extdef.h"
  12.  
  13. int is_debug_on = FALSE; // JMH
  14.  
  15. /*
  16.  *  The following string is printed when the user fails to supply
  17.  *  sufficient information when running the program.
  18.  */
  19.  
  20. static char usage_msg [] = "\
  21. \n\
  22. RESCONV - Resource Conversion Utility program\n\
  23. \n\
  24. Usage:\n\
  25.   RESCONV <OS/2 src_file> <Windows dst_file>\n\
  26. ";
  27.  
  28.  
  29. static uchar search  [] = {'~', 0};
  30. static uchar replace [] = {'&', 0};
  31.  
  32. ushort cLineCurrent = 1;  /* the current line number */
  33.  
  34.  
  35. /*******************************************************************
  36.  *                                                                 *
  37.  *  LOWER_CASE_CHAR                                                *
  38.  *                                                                 *
  39.  *  This procedure is called to convert a character from upper to  *
  40.  *  lower case.                                                    *
  41.  *                                                                 *
  42.  *******************************************************************/
  43.  
  44. uchar lower_case_char (uchar ch)
  45. {
  46.  
  47. /*  Is it an upper case ASCII character? */
  48.  
  49. if (ch >= 'A' && ch <= 'Z')
  50.     return ch ^ (uchar) ' ';
  51.  
  52. /*  It doesn't have a case. */
  53.  
  54. return ch;
  55. }
  56.  
  57.  
  58. /*******************************************************************
  59.  *                                                                 *
  60.  *  UPPER_CASE_CHAR                                                *
  61.  *                                                                 *
  62.  *  This procedure is called to convert a character from lower to  *
  63.  *  upper case.                                                    *
  64.  *                                                                 *
  65.  *******************************************************************/
  66.  
  67. uchar upper_case_char (uchar ch)
  68. {
  69.  
  70. /*  Is it a lower case ASCII character? */
  71.  
  72. if (ch >= 'a' && ch <= 'z')
  73.     return ch ^ (uchar) ' ';
  74.  
  75. /*  It doesn't have a case. */
  76.  
  77. return ch;
  78. }
  79.  
  80.  
  81.  
  82. /*******************************************************************
  83.  *                                                                 *
  84.  *  GET_CHAR_CASE                                                  *
  85.  *                                                                 *
  86.  *  This procedure is called to get the case of the character.     *
  87.  *  The procedure returns 0 if the character has no case, 1 if     *
  88.  *  the character is lower case, and 2 if the character is upper   *
  89.  *  case.                                                          *
  90.  *                                                                 *
  91.  *******************************************************************/
  92.  
  93. ushort get_char_case (uchar ch)
  94. {
  95.  
  96. /*  Is it a lower case ASCII character? */
  97.  
  98. if (ch >= 'a' && ch <= 'z')
  99.     return char_case_lower;
  100.  
  101. /*  Is it an upper case ASCII character? */
  102.  
  103. if (ch >= 'A' && ch <= 'Z')
  104.     return char_case_upper;
  105.  
  106. /*  It doesn't have a case. */
  107.  
  108. return char_case_none;
  109. }
  110.  
  111.  
  112. /*******************************************************************
  113.  *                                                                 *
  114.  *  EQUAL_IGNORING_CASE                                            *
  115.  *                                                                 *
  116.  *  Determines whether two strings of characters are identical,    *
  117.  *  ignoring the case of the characters.                           *
  118.  *                                                                 *
  119.  *******************************************************************/
  120.  
  121. flag equal_ignoring_case (uchar ptr string1, uchar ptr string2)
  122. {
  123. register uchar a;
  124. register uchar b;
  125.  
  126. if (string1 == NULL || string2 == NULL)
  127.     return FALSE;
  128.  
  129. /*
  130.  *  Loop as long as both strings have some data. We quit if we find
  131.  *  a mismatch in the strings.
  132.  */
  133.  
  134. forever {
  135.     if ((a = *string1++) != (b = *string2++)) {
  136.         if (get_char_case (a) == char_case_lower)
  137.             a = upper_case_char (a);
  138.         if (get_char_case (b) == char_case_lower)
  139.             b = upper_case_char (b);
  140.         }
  141.     if (a != b)
  142.         return (FALSE);
  143.     if (a == 0)
  144.         return (TRUE);
  145.     }
  146. }
  147.  
  148.  
  149. /*******************************************************************
  150.  *                                                                 *
  151.  *  STRING_LENGTH                                                  *
  152.  *                                                                 *
  153.  *  Determines the length of a string of characters, not including *
  154.  *  the final null.                           *
  155.  *                                                                 *
  156.  *******************************************************************/
  157.  
  158. ushort string_length (uchar ptr string)
  159. {
  160. return (_fstrlen (string));
  161. }
  162.  
  163.  
  164. /*******************************************************************
  165.  *                                                                 *
  166.  *  STRING_COPY                            *
  167.  *                                                                 *
  168.  *  Copies the contents of one string of characters into another,  *
  169.  *  returning a pointer to the null terminator of the destination. *
  170.  *                                                                 *
  171.  *******************************************************************/
  172.  
  173. void ptr string_copy (uchar ptr dest, uchar ptr source)
  174. {
  175.  
  176. while (*source)
  177.     *dest++ = *source++;
  178.  
  179. *dest = 0;
  180. return (dest);
  181. }
  182.  
  183. /*******************************************************************
  184.  *                                                                 *
  185.  *  STRING_APPEND                           *
  186.  *                                                                 *
  187.  *  Copies the contents of one string of characters into another,  *
  188.  *  returning a pointer to the null terminator of the destination. *
  189.  *                                                                 *
  190.  *******************************************************************/
  191.  
  192. void ptr string_append (uchar ptr dest, uchar ptr source)
  193. {
  194.  
  195. while (*dest)
  196.     dest++;
  197.  
  198. while (*source)
  199.     *dest++ = *source++;
  200.  
  201. *dest = 0;
  202. return (dest);
  203. }
  204.  
  205.  
  206.  
  207. /*******************************************************************
  208.  *                                                                 *
  209.  *  STRING_REPLACE                                                 *
  210.  *                                                                 *
  211.  *  Searches the given string for characters in the search string. *
  212.  *  Any characters found are replaced with the corresponding       *
  213.  *  character in the replace string.                   *
  214.  *                                                                 *
  215.  *******************************************************************/
  216.  
  217. void string_replace (uchar ptr string, uchar ptr search, uchar ptr replace)
  218. {
  219. ushort len;
  220. ushort length;
  221. uchar ptr sp;
  222. uchar ptr ep;
  223.  
  224. length = string_length (string);
  225. while (*search) {
  226.     len = length;
  227.     sp  = string;
  228.     while (ep = _fstrchr (sp, *search)) {
  229.         *ep = *replace;
  230.         len -= ep - sp + 1;
  231.         sp = &ep [1];
  232.         }
  233.     search++;
  234.     replace++;
  235.     }
  236. }
  237.  
  238. /*******************************************************************
  239.  *                                                                 *
  240.  *  DOUBLE_AMPERSANDS                           *
  241.  *                                                                 *
  242.  *  Searches the given string for ampersands and doubles them,       *
  243.  *  so they will not be interpreted incorrectly as mnemonics       *
  244.  *                                                                 *
  245.  *******************************************************************/
  246.  
  247. void double_ampersands (uchar ptr string)
  248. {
  249. ushort length;
  250. uchar ptr sp;
  251. uchar ptr ep;
  252. uchar ptr dp;
  253.  
  254. length = string_length (string);
  255. ep = string;
  256. for (ep = string; *ep; ep++) {
  257.     if (*ep == '&')
  258.     if (length+1 >= max_string_size)
  259.         report_error (err_string_too_long, 0, "doubling ampersands");
  260.     else {
  261.         dp = string+length+1;
  262.         sp = string+length;
  263.         while (sp >= ep)
  264.         *dp-- = *sp--;
  265.         *ep = '&';
  266.         length++;
  267.         ep++;
  268.         }
  269.     }
  270. }
  271.  
  272.  
  273.  
  274. /**************************************************************************
  275.  *                                                                        *
  276.  *  REPORT_ERROR                                                          *
  277.  *                                                                        *
  278.  *  This procedure reports the indicated error and exits the program.     *
  279.  *                                                                        *
  280.  **************************************************************************/
  281.  
  282. void report_error (ushort error, ushort token, uchar ptr string)
  283. {
  284. uchar   ptr msg;
  285.  
  286. /*  Case on the error and print the message. */
  287.  
  288. switch (error) {
  289.     case err_full_put_char_buffer:
  290.         msg = "The put_char buffer is full.";
  291.         break;
  292.     case err_full_put_token_buffer:
  293.         msg = "The put_token buffer is full.";
  294.         break;
  295.     case err_no_source_file:
  296.         msg = "No source file is open.";
  297.         break;
  298.     case err_unexpected_comment_char:
  299.         msg = "Unexpected comment character.";
  300.         break;
  301.     case err_unexpected_eof:
  302.         msg = "Unexpected EOF.";
  303.         break;
  304.     case err_string_too_long:
  305.         msg = "The string is too long.";
  306.         break;
  307.     case err_identifier_too_long:
  308.         msg = "The identifier is too long.";
  309.         break;
  310.     case err_value_too_big:
  311.         msg = "The value is too large.";
  312.         break;
  313.     case err_invalid_syntax:
  314.         msg = "Invalid syntax.";
  315.         break;
  316.     case err_invalid_character:
  317.         msg = "Invalid character.";
  318.         break;
  319.     case err_bad_menu_option:
  320.         msg = "Invalid menu option. Line Omitted";
  321.         break;
  322.     case err_bad_load_option:
  323.         msg = "Invalid load option.";
  324.         break;
  325.     case err_bad_dialog_option:
  326.         msg = "Invalid dialog option.";
  327.         break;
  328.     case err_bad_control_class:
  329.         msg = "Invalid dialog control class.";
  330.         break;
  331.     case err_bad_accel_option:
  332.         msg = "Invalid accelerator table option.";
  333.         break;
  334.     case err_convert_resources:
  335.         msg = "Bad token found in convert_resources.";
  336.         break;
  337.     default:
  338.         msg = "Unknown error occurred.";
  339.         break;
  340.     }
  341.  
  342. if (string)
  343.  
  344.     printf ("%s Token = %d Keyword = %s Line = %d \n",
  345.         msg, token, string, cLineCurrent);
  346. else
  347.     printf ("%s Token = %d Line = %d\n", msg, token, cLineCurrent);
  348.  
  349. close_destination_file ();
  350. terminate_input ();
  351. exit(1);
  352. }
  353.  
  354.  
  355. /**************************************************************************
  356.  *                                                                        *
  357.  *  REPORT_WARNING                              *
  358.  *                                                                        *
  359.  *  This procedure reports the indicated warning.              *
  360.  *                                                                        *
  361.  **************************************************************************/
  362.  
  363. void report_warning (uchar ptr szerror, ushort token, uchar ptr string, long value)
  364. {
  365.  
  366. /*  Case on the error and print the message. */
  367.  
  368. if (string)
  369.     printf ("%s Token = %d Keyword = %s Line = %d \n",
  370.         szerror, token, string, cLineCurrent);
  371.  
  372. else if (value)
  373.     printf ("%s Token = %d Keyword = %d Line = %d \n",
  374.         szerror, token, value, cLineCurrent);
  375.  
  376. else
  377.     printf ("%s Token = %d Line = %d\n", szerror, token, cLineCurrent);
  378.  
  379. }
  380.  
  381.  
  382. /***********************************************************************
  383.  *                                                                     *
  384.  *  CONVERT_TO_UPPER                                                   *
  385.  *                                                                     *
  386.  *  This procedure converts the character string to upper case.        *
  387.  *                                                                     *
  388.  ***********************************************************************/
  389.  
  390. void ptr convert_to_upper (uchar ptr string)
  391. {
  392. uchar   ptr sp;                             /* string pointer */
  393.  
  394. sp = string;
  395. while (*sp) {
  396.     *sp = upper_case_char (*sp);
  397.     sp++;
  398.     }
  399.  
  400. return sp;
  401. }
  402.  
  403.  
  404. /**************************************************************************
  405.  *                                                                        *
  406.  *  CONVERT_RESOURCE                                                      *
  407.  *                                                                        *
  408.  *  This procedure is called to convert a resource statement.             *
  409.  *                                                                        *
  410.  **************************************************************************/
  411.  
  412. void convert_resource (void)
  413. {
  414. ushort      token;
  415. uchar   ptr string;
  416. long        value;
  417.  
  418. /*  Get the resource type identifier. */
  419.  
  420. if ((token = get_token ()) == tok_numeric)
  421.     value = current_token_value ();
  422. else {
  423.     string = _fmalloc (string_length (current_token_string ()) + 1);
  424.     string_copy (string, current_token_string ());
  425.     }
  426.  
  427. /*  Output the resource name identifier. */
  428.  
  429. if (get_token () == tok_numeric)
  430.     output_value (current_token_value ());
  431. else
  432.     output_token (current_token_string ());
  433.  
  434. /*  Output the resource type identifier. */
  435.  
  436. if (token == tok_numeric)
  437.     output_value (value);
  438. else {
  439.     output_token (string);
  440.     _ffree (string);
  441.     }
  442.  
  443. /*  Output the file name. */
  444.  
  445. if ((token = get_token ()) == tok_string)
  446.     output_string (current_token_string ());
  447. else
  448.     output_token (current_token_string ());
  449. }
  450.  
  451.  
  452. /**************************************************************************
  453.  *                                                                        *
  454.  *  PROCESS_RCINCLUDE                                                     *
  455.  *                                                                        *
  456.  *  This procedure is called to process an rcinclude statement.           *
  457.  *                                                                        *
  458.  **************************************************************************/
  459.  
  460. void process_rcinclude (void)
  461. {
  462. ushort  token;
  463.  
  464. /*  Get the filename token and open the source file. */
  465.  
  466. token = get_token ();
  467. open_source_file (current_token_string ());
  468. }
  469.  
  470.  
  471. /**************************************************************************
  472.  *                                                                        *
  473.  *  PROCESS_DLGINCLUDE                              *
  474.  *                                                                        *
  475.  *  This procedure is called to process an dlginclude statement.      *
  476.  *                                                                        *
  477.  **************************************************************************/
  478.  
  479. void process_dlginclude (void)
  480. {
  481. ushort  token;
  482.  
  483. /*  Get the id token */
  484. token = get_token ();
  485.  
  486. token = get_token ();
  487.  
  488. /* someday should add byron's new support */
  489. }
  490.  
  491.  
  492. /**************************************************************************
  493.  *                                                                        *
  494.  *  CONVERT_STRINGTABLE                                                   *
  495.  *                                                                        *
  496.  *  This procedure is called to convert a stringtable statement.          *
  497.  *                                                                        *
  498.  *  Syntax:                                                               *
  499.  *      STRINGTABLE                                                       *
  500.  *      BEGIN                                                             *
  501.  *          stringid, string                                              *
  502.  *      END                                                               *
  503.  *                                                                        *
  504.  **************************************************************************/
  505.  
  506. void convert_stringtable (void)
  507. {
  508. ushort      token;
  509. uchar   ptr string;
  510.  
  511. /*  Output the STRINGTABLE keyword. */
  512.  
  513. output_token ("STRINGTABLE");
  514.  
  515. /*  Output the BEGIN keyword. */
  516.  
  517. output_newline ();
  518. token = get_token ();
  519. output_token ("BEGIN");
  520.  
  521. /*
  522.  *  Until we've seen the END keyword or the EOF, output the information
  523.  *  for each of the strings.
  524.  */
  525.  
  526. while ((token = get_token ()) != tok_end && token != tok_eof) {
  527.     /*
  528.      *  Output the string identifier.
  529.      */
  530.     output_newline ();
  531.     output_tab (1);
  532.     if (token == tok_numeric)
  533.         output_value (current_token_value ());
  534.     else
  535.         output_token (current_token_string ());
  536.     /*
  537.      *  Output the comma.
  538.      */
  539.     output_token (",");
  540.     /*
  541.      *  Output the string.
  542.      */
  543.     token = get_token ();
  544.     if (token == tok_comma)
  545.     token = get_token();
  546.     string = current_token_string ();
  547.     double_ampersands(string);
  548.     string_replace (string, search, replace);
  549.     output_string (string);
  550.     }
  551.  
  552. /*  Output the END keyword. */
  553.  
  554. output_newline ();
  555. output_token ("END");
  556. }
  557.  
  558.  
  559. /**************************************************************************
  560.  *                                                                        *
  561.  *  CONVERT_POINTER                                                       *
  562.  *                                                                        *
  563.  *  This procedure is called to convert a pointer statement.              *
  564.  *                                                                        *
  565.  *  Syntax:                                                               *
  566.  *      idvalue CURSOR filename                                           *
  567.  *                                                                        *
  568.  **************************************************************************/
  569.  
  570. void convert_pointer (void)
  571. {
  572.     ushort      token;
  573.     ushort      done;
  574.  
  575. /*  Output the CURSOR keyword.
  576.     ==========================  */
  577.  
  578.     output_token ("CURSOR");
  579.  
  580. /*  Output the identifier value.
  581.     ============================  */
  582.  
  583.     token = get_token ();
  584.     if (token == tok_numeric)
  585.         output_value (current_token_value ());
  586.     else if (current_token_string() != NULL)
  587.         output_token (current_token_string ());
  588.  
  589. /*  Output option keywords and then the file name.
  590.     ==============================================  */
  591.  
  592.     done = 0;
  593.     while (!done) {
  594.         token = get_token ();
  595.  
  596.         switch (token) {
  597.         case tok_preload:
  598.             output_token("PRELOAD");
  599.             break;
  600.         case tok_loadoncall:
  601.             output_token("LOADONCALL");
  602.             break;
  603.         case tok_fixed:
  604.             output_token("FIXED");
  605.             break;
  606.         case tok_moveable:
  607.             output_token("MOVEABLE");
  608.             break;
  609.         case tok_discardable:
  610.             output_token("DISCARDABLE");
  611.             break;
  612.         default:
  613.             if (current_token_string() != NULL)
  614.                 output_token (current_token_string ());
  615.             done = 1;
  616.             break;
  617.         }
  618.     }
  619. }
  620.  
  621.  
  622. #define OPTIONSUBMENU 1
  623. #define OPTIONSEPARATOR 2
  624.  
  625. /**************************************************************************
  626.  *                                                                        *
  627.  *  CONVERT_MENU_OPTIONS                                                  *
  628.  *                                                                        *
  629.  *  This procedure is called to convert menu item options.                *
  630.  *  returns OPTIONSUBMENU if it's submenu                                 *
  631.  *  returns OPTIONSEPARATOR if it's a separator                           *
  632.  *  otherwise, returns 0.                                                                      *
  633.  *                                                                        *
  634.  **************************************************************************/
  635.  
  636. ushort convert_menu_options (uchar ptr buffer)
  637. {
  638.     ushort      token;
  639.     ushort        ret = 0;
  640.     ushort      error = 0;
  641.  
  642. /*  While we have options, read and process them.
  643.     =============================================  */
  644.  
  645.     while ((token = get_token ()) == tok_comma || token == tok_bitor) {
  646.  
  647. /*      Get the token to process.
  648.         =========================  */
  649.  
  650.         token = get_token ();
  651.  
  652. /*      If we've encountered an error, don't bother to process.
  653.         ======================================================= */
  654.  
  655.         if (error)
  656.             continue;
  657.  
  658. /*      Otherwise, process this option.
  659.         =============================== */
  660.  
  661.         switch (token) {
  662.  
  663.         case tok_mia_disabled:
  664.             if (buffer)
  665.                 string_append(buffer, ", CHECKED");
  666.             else
  667.                 output_token (", CHECKED");
  668.             break;
  669.  
  670.         case tok_mia_checked:
  671.             if (buffer)
  672.                 string_append(buffer, ", INACTIVE");
  673.             else
  674.                 output_token (", INACTIVE");
  675.             break;
  676.  
  677.         case tok_mis_bitmap:
  678.             report_warning("Warning -- MIS_BITMAP not supported. ", token, NULL, 0L);
  679.             error = 1;
  680.             break;          
  681.  
  682.         case tok_mis_breakseparator:
  683.             if (buffer)
  684.                 string_append(buffer, ", MENUBARBREAK");
  685.             else
  686.                 output_token (", MENUBARBREAK");
  687.             break;
  688.  
  689.         case tok_mis_break:
  690.             if (buffer)
  691.                 string_append(buffer, ", MENUBREAK");
  692.             else
  693.                 output_token (", MENUBREAK");
  694.             break;
  695.  
  696.         case tok_mis_ownerdraw:
  697.             if (buffer)
  698.                 string_append(buffer, ", CHECKED");
  699.             else
  700.                 output_token ("CHECKED");
  701.             break;
  702.  
  703.         case tok_mis_separator:
  704.             ret = OPTIONSEPARATOR;
  705.             break;
  706.  
  707.         case tok_mis_text:
  708.             break;
  709.  
  710.         case tok_mis_submenu:
  711.             ret = OPTIONSUBMENU;
  712.             break;
  713.  
  714.         case tok_mis_buttonseparator:
  715.             report_warning("Warning - MIS_BUTTONSEPARATOR not supported.", token, current_token_string(),0);
  716.             break;
  717.  
  718.         case tok_mis_syscommand:
  719.             report_warning("Warning - MIS_SYSCOMMAND not supported.", token, current_token_string(),0);
  720.             error = 1;
  721.             break;
  722.  
  723.         default:
  724.             // report_error (err_bad_menu_option, token, current_token_string ());
  725.             report_warning("Invalid menu option.  Option omitted.", token, NULL, 0L);
  726.             error = 1;
  727.             break;
  728.         }
  729.     }
  730.  
  731. /*  Put the last token back. */
  732.  
  733. put_token ();
  734. return(ret);
  735. }
  736.  
  737.  
  738. /**************************************************************************
  739.  *                                                                        *
  740.  *  CONVERT_MENU_ITEMS                                                    *
  741.  *                                                                        *
  742.  *  This procedure is called to convert a menuitem statement.             *
  743.  *                                                                        *
  744.  *  Syntax:                                                               *
  745.  *      POPUP text, [option-list]                                         *
  746.  *      BEGIN                                                             *
  747.  *          item-definitions                                              *
  748.  *      END                                                               *
  749.  *  or                                                                    *
  750.  *      MENUITEM text, result, [option-list]                              *
  751.  *  or                                                                    *
  752.  *      MENUITEM SEPARATOR                                                *
  753.  *                                                                        *
  754.  **************************************************************************/
  755.  
  756. void convert_menu_items (ushort level)
  757. {
  758.     ushort      token;
  759.     uchar   ptr string;
  760.     uchar    ptr buffer;
  761.     uchar ptr bufferTmp;
  762.     uchar    buf[40];
  763.     uchar    ptr buffer2;
  764.     ushort        option;
  765.  
  766. /*  Allocate buffer in case of MIS_SUBMENU.
  767.     =======================================  */
  768.  
  769.     buffer = _fmalloc (max_string_size);
  770.     buffer2 = _fmalloc (max_string_size);
  771.  
  772. /*  Output the BEGIN keyword.
  773.     =========================  */
  774.  
  775.     output_newline ();
  776.     output_tab (level + 1);
  777.     token = get_token ();
  778.     output_token ("BEGIN");
  779.  
  780. /*  Until we've seen the END keyword or the EOF, output the information
  781.     for each of the menu items.
  782.     ===================================================================  */
  783.  
  784.     while ((token = get_token ()) != tok_end && token != tok_eof) {
  785.  
  786.         output_newline ();
  787.         output_tab (level + 1);
  788.  
  789. /*      If this menu item has submenus, output the POPUP keyword.
  790.         =========================================================  */
  791.  
  792.         if (token == tok_submenu) {
  793.             output_token ("POPUP");
  794.  
  795.             //  Output the menu item name.
  796.  
  797.             token = get_token ();
  798.             if ((string = current_token_string ()) == NULL)
  799.                 string = ""; // was: string = current_token_string ();
  800.             double_ampersands(string);
  801.             string_replace (string, search, replace);
  802.             output_string (string);
  803.  
  804.             //  Get the comma and submenu identifier (which isn't used for
  805.             //  windows).
  806.  
  807.             token = get_token ();         // Get the comma
  808.             if (token == tok_comma)
  809.                 token = get_token ();     // If it was the comma, get the id
  810.             else
  811.                 put_token();              // If not a comma, put it back
  812.  
  813.             // Get any terminating commas.
  814.  
  815.             token = get_token();
  816.             if (token != tok_comma)
  817.                 put_token();
  818.  
  819.             //  Convert the menu options.
  820.  
  821.             convert_menu_options (NULL);   
  822.  
  823.             //  Get the BEGIN keyword and convert the menu items.
  824.  
  825.             convert_menu_items (level + 1);
  826.         }
  827.  
  828. /*      If a regular item or separator, output the MENUITEM keyword.
  829.         ============================================================  */
  830.  
  831.         else if (token == tok_menuitem) {
  832.  
  833.             string_copy (buffer, "MENUITEM ");
  834.  
  835.             //  See if this is a separator or menu text.
  836.  
  837.             if ((token = get_token ()) == tok_separator) {
  838.                 string_append (buffer, "SEPARATOR ");
  839.             }
  840.             else {
  841.                 if ((string = current_token_string ()) == NULL)
  842.                     string = "";
  843.                 double_ampersands(string);
  844.                 string_replace (string, search, replace);
  845.  
  846.                 // Save menu text in case of popup.
  847.  
  848.                 string_copy(buffer2, string);
  849.                 string_append(buffer, "\"");
  850.                 string_append (buffer, string);
  851.                 string_append(buffer, "\"");
  852.  
  853.                 //  Output the comma and menu identifier.
  854.  
  855.                 token = get_token ();
  856.                 string_append (buffer, ", ");
  857.                 token = get_token ();
  858.                 if (token == tok_numeric) {
  859.                     ltoa (current_token_value(), buf, 10);
  860.                     string_append(buffer, buf);
  861.                 } else {
  862.                     if (bufferTmp = current_token_string ()) {
  863.                         string_append(buffer, bufferTmp);
  864.                     }
  865.                 }
  866.  
  867.                 //  Convert the options list.
  868.  
  869.                 option = convert_menu_options (buffer);
  870.  
  871.                 //  If the options say it's a SUBMENU, make it a POPUP.
  872.  
  873.                 if (option == OPTIONSUBMENU) {
  874.                     string_copy (buffer, "POPUP ");
  875.                     string_append(buffer, "\"");
  876.                     string_append(buffer, buffer2);
  877.                     string_append(buffer, "\"");
  878.                     output_token(buffer);
  879.                     convert_menu_items(level+1);
  880.                 }
  881.  
  882.                 //  If the options say separator, make it so.
  883.  
  884.                 else if (option == OPTIONSEPARATOR)
  885.                     output_token("MENUITEM SEPARATOR");
  886.  
  887.                 // Otherwise, just output the options.
  888.  
  889.                 else
  890.                     output_token(buffer);
  891.             }
  892.  
  893. /*      Unrecognized token in the menu description.
  894.         =========================================== */
  895.  
  896.         } else {
  897.             report_error (err_bad_menu_option, token, current_token_string ());
  898.         }
  899.  
  900. /*  Continue looping until we reach the END keyword or end-of-file.
  901.     ===============================================================  */
  902.     }
  903.  
  904. /*  Output the END keyword. */
  905.  
  906.     output_newline ();
  907.     output_tab (level + 1);
  908.     output_token ("END");
  909.     _ffree (buffer);
  910.     _ffree (buffer2);
  911. }
  912.  
  913.  
  914. /**************************************************************************
  915.  *                                                                        *
  916.  *  CONVERT_MENU                                                          *
  917.  *                                                                        *
  918.  *  This procedure is called to convert a menu statement.                 *
  919.  *                                                                        *
  920.  *  Syntax:                                                               *
  921.  *      menuid MENU [load-option] [mem-option]                            *
  922.  *      BEGIN                                                             *
  923.  *          item-definitions                                              *
  924.  *      END                                                               *
  925.  *                                                                        *
  926.  **************************************************************************/
  927.  
  928. void convert_menu (void)
  929. {
  930.     ushort      token;
  931.  
  932. /*  Output the menu identifier.
  933.     =========================== */
  934.  
  935.     token = get_token ();
  936.     if (token == tok_numeric)
  937.         output_value (current_token_value ());
  938.     else if (current_token_string() != NULL)
  939.         output_token (current_token_string ());
  940.  
  941. /*  Output the MENU keyword.
  942.     ======================== */
  943.  
  944.     output_token ("MENU");
  945.  
  946. /*  Output any load and memory options.
  947.     =================================== */
  948.  
  949.     while ((token = get_token ()) != tok_begin && token != tok_eof) {
  950.         switch (token) {
  951.         case tok_discardable:
  952.             output_token ("DISCARDABLE");
  953.             break;
  954.         case tok_fixed:
  955.             output_token ("FIXED");
  956.             break;
  957.         case tok_moveable:
  958.             output_token ("MOVEABLE");
  959.             break;
  960.         case tok_loadoncall:
  961.             output_token ("LOADONCALL");
  962.             break;
  963.         case tok_preload:
  964.             output_token ("PRELOAD");
  965.             break;
  966.         default:
  967.             report_error (err_bad_load_option, token, current_token_string ());
  968.             break;
  969.         }
  970.     }
  971.  
  972. /*  Replace the BEGIN or eof token that caused us to exit the loop.
  973.     =============================================================== */
  974.  
  975.     put_token ();
  976.  
  977. /*  Convert the menu items.
  978.     ======================= */
  979.  
  980.     if (token != tok_eof)
  981.         convert_menu_items (0);
  982. }
  983.  
  984. /**************************************************************************
  985.  *                                                                        *
  986.  *  CONVERT_HELPTABLE                              *
  987.  *                                                                        *
  988.  *  This procedure is called to convert a help table.              *
  989.  *                                                                        *
  990.  **************************************************************************/
  991.  
  992. void convert_helptable (void)
  993. {
  994.     ushort token;
  995.  
  996.     report_warning("Helptables not supported.", 0, NULL, 0);
  997.  
  998.     for (token = get_token();
  999.      token != tok_end && token != tok_eof;
  1000.      token = get_token())
  1001.     ;
  1002. }
  1003.  
  1004. /**************************************************************************
  1005.  *                                                                        *
  1006.  *  CONVERT_HELPSUBTABLE                          *
  1007.  *                                                                        *
  1008.  *  This procedure is called to convert a help table.              *
  1009.  *                                                                        *
  1010.  **************************************************************************/
  1011.  
  1012. void convert_helpsubtable (void)
  1013. {
  1014.     ushort token;
  1015.  
  1016.     report_warning("Helpsubtables not supported.", 0, NULL, 0);
  1017.  
  1018.     for (token = get_token();
  1019.      token != tok_end && token != tok_eof;
  1020.      token = get_token())
  1021.     ;
  1022. }
  1023.  
  1024. /**************************************************************************
  1025.  *                                                                        *
  1026.  *  CONVERT_INCLUDE                                                       *
  1027.  *                                                                        *
  1028.  *  This procedure is called to convert an include statement.             *
  1029.  *                                                                        *
  1030.  **************************************************************************/
  1031.  
  1032. void convert_include (void)
  1033. {
  1034. ushort      token;
  1035. uchar   ptr string;
  1036.  
  1037. /*  Get the filename. */
  1038.  
  1039. token = get_token ();
  1040. string = current_token_string ();
  1041.  
  1042. /*
  1043.  *  If this is the <os2.h> include file, we need to change it to <windows.h>.
  1044.  *  We also need to undefine a define because we need some defines that are
  1045.  *  not included.
  1046.  *
  1047.  *  If this is not <os2.h>, output the #include and the filename.
  1048.  */
  1049.  
  1050. output_newline();
  1051. if (equal_ignoring_case (string, "<os2.h>")) {
  1052.     output_token ("#undef RC_INVOKED");
  1053.     output_newline ();
  1054.     output_token ("#include");
  1055.     output_token ("<windows.h>");
  1056.     }
  1057. else {
  1058.     output_token ("#include");
  1059.     if (token == tok_string)
  1060.         output_string (string);
  1061.     else
  1062.         output_token (string);
  1063.     }
  1064. }
  1065.  
  1066.  
  1067. /**************************************************************************
  1068.  *                                                                        *
  1069.  *  CONVERT_ICON                                                          *
  1070.  *                                                                        *
  1071.  *  This procedure is called to convert an icon statement.                *
  1072.  *                                                                        *
  1073.  *  Syntax:                                                               *
  1074.  *      idvalue ICON filename                                             *
  1075.  *                                                                        *
  1076.  **************************************************************************/
  1077.  
  1078. void convert_icon (void)
  1079. {
  1080.     ushort      token;
  1081.     ushort      done;
  1082.  
  1083. /*  Output the ICON keyword. */
  1084.  
  1085.     output_token ("ICON");
  1086.  
  1087. /*  Output the identifier value. */
  1088.  
  1089.     token = get_token ();
  1090.     if (token == tok_numeric)
  1091.         output_value (current_token_value ());
  1092.     else if (token == tok_constant)
  1093.         output_token (current_token_string ());
  1094.     else if (current_token_string() != NULL)
  1095.         output_string (current_token_string());
  1096.  
  1097. /*  Output option keywords and then the file name.
  1098.     ==============================================  */
  1099.  
  1100.     done = 0;
  1101.     while (!done) {
  1102.         token = get_token ();
  1103.  
  1104.         switch (token) {
  1105.         case tok_preload:
  1106.             output_token("PRELOAD");
  1107.             break;
  1108.         case tok_loadoncall:
  1109.             output_token("LOADONCALL");
  1110.             break;
  1111.         case tok_fixed:
  1112.             output_token("FIXED");
  1113.             break;
  1114.         case tok_moveable:
  1115.             output_token("MOVEABLE");
  1116.             break;
  1117.         case tok_discardable:
  1118.             output_token("DISCARDABLE");
  1119.             break;
  1120.         default:
  1121.             if (current_token_string() != NULL)
  1122.                 output_token (current_token_string ());
  1123.             done = 1;
  1124.             break;
  1125.         }
  1126.     }
  1127. }
  1128.  
  1129.  
  1130. /**************************************************************************
  1131.  *                                                                        *
  1132.  *  CONVERT_DIALOG_OPTIONS                                                *
  1133.  *                                                                        *
  1134.  *  This procedure is called to convert a dialog elements options.        *
  1135.  *                                                                        *
  1136.  **************************************************************************/
  1137.  
  1138. void convert_dialog_options (flag output)
  1139. {
  1140. ushort      token;
  1141.  
  1142. /*
  1143.  *  Until we find the 'stopper' keywords or the EOF, output the option
  1144.  *  information.
  1145.  */
  1146.  
  1147. for (token = get_token();
  1148.      token != tok_begin && token != tok_end && token != tok_eof &&
  1149.      token != tok_ltext && token != tok_rtext && token != tok_ctext &&
  1150.      token != tok_radiobutton && token != tok_autoradiobutton &&
  1151.      token != tok_checkbox && token != tok_autocheckbox &&
  1152.      token != tok_pushbutton && token != tok_defpushbutton &&
  1153.      token != tok_listbox && token != tok_groupbox && token != tok_entryfield
  1154.      && token != tok_icon;
  1155.      token = get_token()){
  1156.  
  1157.     /*
  1158.      *    If we have output something, output a '|' before the next keyword.
  1159.      */
  1160.     /*
  1161.      *  Output the option.
  1162.      */
  1163.     switch (token) {
  1164.         case tok_bs_autocheckbox:
  1165.         if (output)
  1166.         output_token ("|");
  1167.             output_token ("BS_AUTOCHECKBOX");
  1168.         output = TRUE;
  1169.             break;
  1170.  
  1171.         case tok_bs_autoradiobutton:
  1172.         if (output)
  1173.         output_token ("|");
  1174.             output_token ("BS_AUTORADIOBUTTON");
  1175.         output = TRUE;
  1176.             break;
  1177.  
  1178.         case tok_bs_checkbox:
  1179.         if (output)
  1180.         output_token ("|");
  1181.             output_token ("BS_CHECKBOX");
  1182.         output = TRUE;
  1183.             break;
  1184.  
  1185.         case tok_bs_default:
  1186.         if (output)
  1187.         output_token ("|");
  1188.             output_token ("BS_DEFPUSHBUTTON");
  1189.         output = TRUE;
  1190.             break;
  1191.  
  1192.         case tok_bs_help:
  1193.             break;
  1194.  
  1195.         case tok_bs_nopointerfocus:
  1196.             break;
  1197.  
  1198.         case tok_bs_pushbutton:
  1199.         if (output)
  1200.         output_token ("|");
  1201.             output_token ("BS_PUSHBUTTON");
  1202.         output = TRUE;
  1203.             break;
  1204.  
  1205.         case tok_bs_radiobutton:
  1206.         if (output)
  1207.         output_token ("|");
  1208.             output_token ("BS_RADIOBUTTON");
  1209.         output = TRUE;
  1210.             break;
  1211.  
  1212.         case tok_cbs_dropdown:
  1213.         if (output)
  1214.         output_token ("|");
  1215.             output_token ("CBS_DROPDOWN");
  1216.         output = TRUE;
  1217.             break;
  1218.  
  1219.         case tok_cbs_dropdownlist:
  1220.         if (output)
  1221.         output_token ("|");
  1222.             output_token ("CBS_DROPDOWNLIST");
  1223.         output = TRUE;
  1224.             break;
  1225.  
  1226.         case tok_cbs_simple:
  1227.         if (output)
  1228.         output_token ("|");
  1229.             output_token ("CBS_SIMPLE");
  1230.         output = TRUE;
  1231.             break;
  1232.  
  1233.         case tok_dt_bottom:
  1234.         if (output)
  1235.         output_token ("|");
  1236.             output_token ("DT_TOP");
  1237.         output = TRUE;
  1238.             break;
  1239.  
  1240.         case tok_dt_center:
  1241.         if (output)
  1242.         output_token ("|");
  1243.             output_token ("DT_CENTER");
  1244.         output = TRUE;
  1245.             break;
  1246.  
  1247.         case tok_dt_left:
  1248.         if (output)
  1249.         output_token ("|");
  1250.             output_token ("DT_LEFT");
  1251.         output = TRUE;
  1252.             break;
  1253.  
  1254.         case tok_dt_mnemonic:
  1255.             break;
  1256.  
  1257.         case tok_dt_right:
  1258.         if (output)
  1259.         output_token ("|");
  1260.             output_token ("DT_RIGHT");
  1261.         output = TRUE;
  1262.             break;
  1263.  
  1264.         case tok_dt_top:
  1265.         if (output)
  1266.         output_token ("|");
  1267.             output_token ("DT_TOP");
  1268.         output = TRUE;
  1269.             break;
  1270.  
  1271.         case tok_dt_vcenter:
  1272.         if (output)
  1273.         output_token ("|");
  1274.             output_token ("DT_CENTER");
  1275.         output = TRUE;
  1276.             break;
  1277.  
  1278.         case tok_dt_wordbreak:
  1279.         if (output)
  1280.         output_token ("|");
  1281.             output_token ("DT_WORDBREAK");
  1282.         output = TRUE;
  1283.             break;
  1284.  
  1285.     case tok_dt_halftone:
  1286.         if (output)
  1287.         output_token ("|");
  1288.         output_token ("DT_HALFTONE");
  1289.         output = TRUE;
  1290.         break;
  1291.  
  1292.         case tok_es_autoscroll:
  1293.         if (output)
  1294.         output_token ("|");
  1295.             output_token ("ES_AUTOHSCROLL");
  1296.         output = TRUE;
  1297.             break;
  1298.  
  1299.         case tok_es_center:
  1300.         if (output)
  1301.         output_token ("|");
  1302.             output_token ("ES_CENTER");
  1303.         output = TRUE;
  1304.             break;
  1305.  
  1306.         case tok_es_left:
  1307.         if (output)
  1308.         output_token ("|");
  1309.             output_token ("ES_LEFT");
  1310.         output = TRUE;
  1311.             break;
  1312.  
  1313.         case tok_es_margin:
  1314.             break;
  1315.  
  1316.         case tok_es_right:
  1317.         if (output)
  1318.         output_token ("|");
  1319.             output_token ("ES_RIGHT");
  1320.         output = TRUE;
  1321.             break;
  1322.  
  1323.     case tok_mls_vscroll:
  1324.         if (output)
  1325.         output_token ("|");
  1326.         output_token ("ES_AUTOVSCROLL");
  1327.         output = TRUE;
  1328.             break;
  1329.  
  1330.     case tok_mls_wordwrap:
  1331.         break;
  1332.  
  1333.     case tok_mls_border:
  1334.         if (output)
  1335.         output_token ("|");
  1336.         output_token ("WS_BORDER");
  1337.         output = TRUE;
  1338.         break;
  1339.  
  1340.         case tok_fcf_sysmenu:
  1341.         if (output)
  1342.         output_token ("|");
  1343.             output_token ("WS_SYSMENU");
  1344.         output = TRUE;
  1345.             break;
  1346.  
  1347.         case tok_fcf_titlebar:
  1348.         if (output)
  1349.         output_token ("|");
  1350.             output_token ("WS_CAPTION");
  1351.         output = TRUE;
  1352.             break;
  1353.  
  1354.         case tok_fs_border:
  1355.         if (output)
  1356.         output_token ("|");
  1357.             output_token ("DS_MODALFRAME");
  1358.         output = TRUE;
  1359.             break;
  1360.  
  1361.         case tok_fs_dlgborder:
  1362.     case tok_fcf_dlgborder:
  1363.         if (output)
  1364.         output_token ("|");
  1365.             output_token ("DS_MODALFRAME");
  1366.         output = TRUE;
  1367.             break;
  1368.  
  1369.         case tok_fs_mousealign:
  1370.             break;
  1371.  
  1372.     case tok_fcf_icon:
  1373.     case tok_fs_icon:
  1374.         report_warning("Icon style on dialogs not supported.", token, current_token_string(), 0);
  1375.         break;
  1376.  
  1377.     case tok_fcf_minbutton:
  1378.         report_warning("Minimize style on dialogs not supported.", token, current_token_string(), 0);
  1379.         break;
  1380.  
  1381.         case tok_fs_nobytealign:
  1382.     case tok_fcf_nobytealign:
  1383.             break;
  1384.  
  1385.         case tok_ls_horzscroll:
  1386.         if (output)
  1387.         output_token ("|");
  1388.             output_token ("WS_HSCROLL");
  1389.         output = TRUE;
  1390.             break;
  1391.  
  1392.         case tok_ls_multiplesel:
  1393.         if (output)
  1394.         output_token ("|");
  1395.             output_token ("LBS_MULTIPLESEL");
  1396.         output = TRUE;
  1397.             break;
  1398.  
  1399.     case tok_ls_ownerdraw:
  1400.         if (output)
  1401.         output_token ("|");
  1402.         output_token ("LBS_OWNERDRAWFIXED");
  1403.         output = TRUE;
  1404.         break;
  1405.  
  1406.         case tok_sbs_horz:
  1407.         if (output)
  1408.         output_token ("|");
  1409.             output_token ("SBS_HORZ");
  1410.         output = TRUE;
  1411.             break;
  1412.  
  1413.         case tok_sbs_vert:
  1414.         if (output)
  1415.         output_token ("|");
  1416.             output_token ("SBS_VERT");
  1417.         output = TRUE;
  1418.             break;
  1419.  
  1420.     case tok_ss_icon:
  1421.         case tok_ss_fgndframe:
  1422.         case tok_ss_groupbox:
  1423.         case tok_ss_halftoneframe:
  1424.             /*
  1425.              *  This information was already output with the static
  1426.              *  style.
  1427.              */
  1428.             break;
  1429.  
  1430.         case tok_ss_text:
  1431.             break;
  1432.  
  1433.         case tok_ws_clipsiblings:
  1434.         if (output)
  1435.         output_token ("|");
  1436.             output_token ("WS_CLIPSIBLINGS");
  1437.         output = TRUE;
  1438.             break;
  1439.  
  1440.         case tok_ws_group:
  1441.         if (output)
  1442.         output_token ("|");
  1443.             output_token ("WS_GROUP");
  1444.         output = TRUE;
  1445.             break;
  1446.  
  1447.         case tok_ws_savebits:
  1448.         if (output)
  1449.         output_token ("|");
  1450.             output_token ("CS_SAVEBITS");
  1451.         output = TRUE;
  1452.             break;
  1453.  
  1454.         case tok_ws_tabstop:
  1455.         if (output)
  1456.         output_token ("|");
  1457.             output_token ("WS_TABSTOP");
  1458.         output = TRUE;
  1459.             break;
  1460.  
  1461.         case tok_ws_visible:
  1462.         if (output)
  1463.         output_token ("|");
  1464.             output_token ("WS_VISIBLE");
  1465.         output = TRUE;
  1466.             break;
  1467.  
  1468.     case tok_numeric:
  1469.         report_warning ("Warning - Unknown window style.", token, NULL, current_token_value ());
  1470.         output_value(current_token_value());
  1471.         break;
  1472.  
  1473.     case tok_string:
  1474.         report_warning ("Warning - Unknown window style.", token, current_token_string (), 0);
  1475.         output_string(current_token_string());
  1476.         break;
  1477.  
  1478.     case tok_comma:
  1479.         put_token();
  1480.         break;  //JMH
  1481.  
  1482.         default:
  1483.             report_error (err_bad_dialog_option, token, current_token_string ());
  1484.             break;
  1485.         }
  1486.     /*
  1487.      *  Skip over the '|' or ',' characters. If it isn't one of these
  1488.      *  two characters, exit.
  1489.      */
  1490.     if ((token = get_token ()) != tok_bitor && token != tok_comma) {
  1491.         put_token ();
  1492.         return;
  1493.         }
  1494.     }
  1495.  
  1496. /*  Put back the last token. */
  1497.  
  1498. put_token ();
  1499. }
  1500.  
  1501.  
  1502. /**************************************************************************
  1503.  *                                                                        *
  1504.  *  CONVERT_DLGTEMPLATE                                                   *
  1505.  *                                                                        *
  1506.  *  This procedure is called to convert a dlgtemplate statement.          *
  1507.  *                                                                        *
  1508.  *  Syntax:                                                               *
  1509.  *      nameid DIALOG [load-option] [mem-option] x, y, width, height      *
  1510.  *      [option-statements]                                               *
  1511.  *      BEGIN                                                             *
  1512.  *          control-statements                                            *
  1513.  *      END                                                               *
  1514.  *                                                                        *
  1515.  **************************************************************************/
  1516.  
  1517. void convert_dlgtemplate (void)
  1518. {
  1519. ushort        token;
  1520. uchar    ptr string;
  1521. uchar    ptr title;
  1522. long        dlg_width, dlg_height;
  1523. long        x, y, width, height;
  1524. ushort        type;
  1525. ushort        ctltype;
  1526. ushort        fOutputOr;
  1527.  
  1528. /*  Output the name identifier. */
  1529.  
  1530. token = get_token ();
  1531. output_token (current_token_string ());
  1532.  
  1533. /*  Output the DIALOG keyword. */
  1534.  
  1535. output_token ("DIALOG");
  1536.  
  1537. /*
  1538.  *  Until we see the BEGIN keyword of the EOF, output the load and
  1539.  *  memory options.
  1540.  */
  1541.  
  1542. while ((token = get_token ()) != tok_begin && token != tok_eof) {
  1543.     switch (token) {
  1544.         case tok_discardable:
  1545.             output_token ("DISCARDABLE");
  1546.             break;
  1547.         case tok_fixed:
  1548.             output_token ("FIXED");
  1549.             break;
  1550.         case tok_moveable:
  1551.             output_token ("MOVEABLE");
  1552.             break;
  1553.         case tok_loadoncall:
  1554.             output_token ("LOADONCALL");
  1555.             break;
  1556.         case tok_preload:
  1557.             output_token ("PRELOAD");
  1558.             break;
  1559.         default:
  1560.             report_error (err_bad_load_option, token, current_token_string ());
  1561.             break;
  1562.         }
  1563.     }
  1564.  
  1565. /*  Skip over the DIALOG/FRAME keyword and make a copy of the title. */
  1566.  
  1567. type = get_token ();
  1568. token = get_token ();
  1569. title = _fmalloc (string_length (current_token_string ()) + 1);
  1570. string_copy (title, current_token_string ());
  1571.  
  1572. /*  Skip over the comma, second dialog identifier, and another comma. */
  1573.  
  1574. token = get_token ();
  1575. token = get_token ();
  1576. token = get_token ();
  1577.  
  1578. /*  Output the x, y, width, and height values. */
  1579.  
  1580. output_newline ();
  1581. output_tab (2);
  1582.  
  1583. token = get_token ();
  1584. x = current_token_value ();
  1585. output_value (x);
  1586. token = get_token ();
  1587. output_token (",");
  1588.  
  1589. token = get_token ();
  1590. y = current_token_value ();
  1591. output_value (y);
  1592. token = get_token ();
  1593. output_token (",");
  1594.  
  1595. token = get_token ();
  1596. dlg_width = current_token_value ();
  1597. output_value ((long) ((double) dlg_width * .8));
  1598. token = get_token ();
  1599. output_token (",");
  1600.  
  1601. token = get_token ();
  1602. dlg_height = current_token_value ();
  1603. output_value (dlg_height);
  1604. token = get_token ();
  1605.  
  1606. /*  Output the dialog title. */
  1607.  
  1608. output_newline ();
  1609. output_tab (2);
  1610. output_token ("CAPTION");
  1611. output_string (title);
  1612. _ffree (title);
  1613.  
  1614. /*  Output the dialog style information. */
  1615.  
  1616. output_newline ();
  1617. output_tab (2);
  1618. output_token ("STYLE");
  1619. convert_dialog_options (FALSE);
  1620. if (type == tok_frame)
  1621.     output_token (" | WS_CHILD");
  1622.  
  1623. /*  Output the BEGIN keyword. */
  1624.  
  1625. output_newline ();
  1626. output_tab (1);
  1627. token = get_token ();
  1628. output_token ("BEGIN");
  1629.  
  1630. /*
  1631.  *  While there are still control statements in the dialog, convert them.
  1632.  *  Syntax:
  1633.  *      CONTROL text, id, class, style, x, y, width, height
  1634.  */
  1635.  
  1636. for (token = get_token();
  1637.      token != tok_end && token != tok_eof;
  1638.      token = get_token()){
  1639.     /*
  1640.      *  Output the CONTROL keyword.
  1641.      */
  1642.     output_newline ();
  1643.     output_tab (2);
  1644.     output_token ("CONTROL");
  1645.  
  1646.     ctltype = token;
  1647.  
  1648.     /*
  1649.      *  Output the text and a comma.
  1650.      */
  1651.     /* listboxes don't have text */
  1652.     if (ctltype == tok_listbox)
  1653.     output_string("");
  1654.     else {
  1655.     token = get_token ();
  1656.     string = current_token_string ();
  1657.     /* check for ICON case, where text can be a constant */
  1658.     if (token == tok_constant)
  1659.         output_token(string);
  1660.     else {
  1661.         double_ampersands(string);
  1662.         string_replace (string, search, replace);
  1663.         output_string (string);
  1664.         }
  1665.     /* get the following comma */
  1666.     token = get_token ();
  1667.     if (token != tok_comma)
  1668.         put_token();
  1669.     }
  1670.  
  1671.     output_token (",");
  1672.     /*
  1673.      *  Output the control identifier and a comma.
  1674.      */
  1675.     token = get_token ();
  1676.     if (token == tok_numeric)
  1677.         output_value (current_token_value ());
  1678.     else if (token == tok_did_ok)
  1679.     output_token("IDOK");
  1680.     else if (token == tok_did_cancel)
  1681.     output_token("IDCANCEL");
  1682.     else
  1683.         output_token (current_token_string ());
  1684.     token = get_token ();
  1685.     output_token (",");
  1686.     /*
  1687.      *  The next four fields are x, y, width, and height. We need to save
  1688.      *  these off because they are output after the class and style options.
  1689.      */
  1690.     token = get_token ();
  1691.     x = current_token_value ();
  1692.     token = get_token ();
  1693.  
  1694.     token = get_token ();
  1695.     y = current_token_value ();
  1696.     token = get_token ();
  1697.  
  1698.     token = get_token ();
  1699.     width = current_token_value ();
  1700.     token = get_token ();
  1701.  
  1702.     token = get_token ();
  1703.     height = current_token_value ();
  1704.  
  1705.     /* if next thing is a comma, get it */
  1706.     token = get_token ();
  1707.     if (token != tok_comma)
  1708.     put_token();
  1709.  
  1710.     /*
  1711.      *    If using CONTROL syntax, the next option will be the control class.
  1712.      *    If using alternate syntax, fake code into believing there is a style.
  1713.      */
  1714.     if (ctltype == tok_control){
  1715.     type = token = get_token ();
  1716.     }
  1717.     else
  1718.     type = token = ctltype;
  1719.     fOutputOr = FALSE;
  1720.     if (token == wc_static) {
  1721.     /*
  1722.      *  Get the comma and the type of static item.
  1723.      */
  1724.     token = get_token ();
  1725.     token = get_token ();
  1726.     switch (token) {
  1727.         case tok_ss_fgndframe:
  1728.         output_token ("STATIC, SS_GRAYFRAME ");
  1729.         fOutputOr = TRUE;
  1730.         break;
  1731.  
  1732.         case tok_ss_groupbox:
  1733.         output_token ("BUTTON, BS_GROUPBOX");
  1734.         fOutputOr = TRUE;
  1735.         break;
  1736.  
  1737.         case tok_ss_halftoneframe:
  1738.         output_token ("STATIC, SS_GRAYFRAME");
  1739.         fOutputOr = TRUE;
  1740.         break;
  1741.  
  1742.         case tok_ss_text:
  1743.         output_token ("STATIC,");
  1744.         break;
  1745.  
  1746.         case tok_ss_icon:
  1747.         output_token ("STATIC, SS_ICON");
  1748.         fOutputOr = TRUE;
  1749.         break;
  1750.  
  1751.         default:
  1752.         report_error (err_bad_control_class, token, current_token_string ());
  1753.         break;
  1754.         }
  1755.     /*
  1756.      *  Put the static type back to make parsing consistent in
  1757.      *  convert_dialog_options. However, since we've already output
  1758.      *  the information here, convert_dialog_options will just ignore
  1759.      *  the ss_xxx tokens.
  1760.      */
  1761.     put_token ();
  1762.     output_newline ();
  1763.     output_tab (3);
  1764.     }
  1765.     else {
  1766.     switch(token) {
  1767.         case tok_icon:
  1768.         output_token ("STATIC, SS_ICON");
  1769.         fOutputOr = TRUE;
  1770.         break;
  1771.         case tok_ltext:
  1772.         output_token ("STATIC, DT_LEFT");
  1773.         fOutputOr = TRUE;
  1774.         break;
  1775.         case tok_rtext:
  1776.         output_token ("STATIC, DT_RIGHT");
  1777.         fOutputOr = TRUE;
  1778.         break;
  1779.         case tok_ctext:
  1780.         output_token ("STATIC, DT_CENTER");
  1781.         fOutputOr = TRUE;
  1782.         break;
  1783.         case tok_radiobutton:
  1784.         output_token ("BUTTON, BS_RADIOBUTTON");
  1785.         fOutputOr = TRUE;
  1786.         break;
  1787.         case tok_autoradiobutton:
  1788.         output_token ("BUTTON, BS_AUTORADIOBUTTON");
  1789.         fOutputOr = TRUE;
  1790.         break;
  1791.         case tok_checkbox:
  1792.         output_token ("BUTTON, BS_CHECKBOX");
  1793.         fOutputOr = TRUE;
  1794.         break;
  1795.         case tok_autocheckbox:
  1796.         output_token ("BUTTON, BS_AUTOCHECKBOX");
  1797.         fOutputOr = TRUE;
  1798.         break;
  1799.         case tok_pushbutton:
  1800.         output_token ("BUTTON, BS_PUSHBUTTON");
  1801.         fOutputOr = TRUE;
  1802.         break;
  1803.         case tok_defpushbutton:
  1804.         output_token ("BUTTON, BS_DEFPUSHBUTTON");
  1805.         fOutputOr = TRUE;
  1806.         break;
  1807.         case tok_groupbox:
  1808.         output_token ("BUTTON, BS_GROUPBOX");
  1809.         fOutputOr = TRUE;
  1810.         break;
  1811.         case wc_button:
  1812.         output_token ("BUTTON,");
  1813.         break;
  1814.  
  1815.         case wc_combobox:
  1816.         output_token ("COMBOBOX,");
  1817.         break;
  1818.  
  1819.         case wc_mle:
  1820.         output_token ("EDIT, ES_MULTILINE");
  1821.         fOutputOr = TRUE;
  1822.         height += 2;
  1823.         break;
  1824.  
  1825.         case tok_entryfield:
  1826.         type = wc_entryfield;
  1827.         case wc_entryfield:
  1828.         output_token ("EDIT, WS_BORDER");
  1829.         fOutputOr = TRUE;
  1830.         height += 2;
  1831.         break;
  1832.  
  1833.         case tok_listbox:
  1834.         type = wc_listbox;
  1835.         case wc_listbox:
  1836.         output_token ("LISTBOX, LBS_NOTIFY | WS_BORDER | WS_VSCROLL");
  1837.         fOutputOr = TRUE;
  1838.         break;
  1839.  
  1840.         case wc_scrollbar:
  1841.         output_token ("SCROLLBAR,");
  1842.         break;
  1843.  
  1844.         case tok_string:
  1845.         report_warning ("Warning - Unknown control class.", token, current_token_string (), 0);
  1846.         output_string (current_token_string());
  1847.         output_token (",");
  1848.         type = wc_static;
  1849.         break;
  1850.  
  1851.         default:
  1852.         report_error (err_bad_control_class, token, current_token_string ());
  1853.         break;
  1854.         }
  1855.     /*
  1856.      *  Get the comma and output a newline.
  1857.      */
  1858.     token = get_token ();
  1859.     if (token != tok_comma)
  1860.         put_token();
  1861.     output_newline ();
  1862.     output_tab (3);
  1863.     }
  1864.  
  1865.     /*
  1866.      *  Output the style options.
  1867.      */
  1868.     convert_dialog_options (fOutputOr);
  1869.     output_token (",");
  1870.     output_newline ();
  1871.     output_tab (3);
  1872.     /*
  1873.      *  Now we can output the x, y, width, and height information.
  1874.      */
  1875.     output_value ((long) ((double) x * .8));
  1876.     output_token (",");
  1877.     if (type == wc_listbox)
  1878.         output_value (dlg_height - y - height + 2);
  1879.     else
  1880.         output_value (dlg_height - y - height);
  1881.     output_token (",");
  1882.     output_value ((long) ((double) width * .8));
  1883.     output_token (",");
  1884.     if (type == wc_entryfield)
  1885.         output_value (height + 2);
  1886.     else
  1887.         output_value (height);
  1888.     }
  1889.  
  1890. /*  Output the END keyword. */
  1891.  
  1892. output_newline ();
  1893. output_tab (1);
  1894. token = get_token ();
  1895. output_token ("END");
  1896. }
  1897.  
  1898.  
  1899. /**************************************************************************
  1900.  *                                                                        *
  1901.  *  CONVERT_BITMAP                                                        *
  1902.  *                                                                        *
  1903.  *  This procedure is called to convert a bitmap statement.               *
  1904.  *                                                                        *
  1905.  *  Syntax:                                                               *
  1906.  *      idvalue BITMAP filename                                           *
  1907.  *                                                                        *
  1908.  **************************************************************************/
  1909.  
  1910. void convert_bitmap (void)
  1911. {
  1912.     ushort      token;
  1913.     ushort      done;
  1914.  
  1915. /*  Output the identifier value.
  1916.     ============================  */
  1917.  
  1918.     token = get_token ();
  1919.     if (token == tok_numeric)
  1920.         output_value (current_token_value ());
  1921.     else if (current_token_string() != NULL)
  1922.         output_token (current_token_string ());
  1923.  
  1924. /*  Output the PM12BITMAP keyword.
  1925.     ==============================  */
  1926.  
  1927.     output_token ("BITMAP");
  1928.  
  1929. /*  Output option keywords and then the file name.
  1930.     ==============================================  */
  1931.  
  1932.     done = 0;
  1933.     while (!done) {
  1934.         token = get_token ();
  1935.  
  1936.         switch (token) {
  1937.         case tok_preload:
  1938.             output_token("PRELOAD");
  1939.             break;
  1940.         case tok_loadoncall:
  1941.             output_token("LOADONCALL");
  1942.             break;
  1943.         case tok_fixed:
  1944.             output_token("FIXED");
  1945.             break;
  1946.         case tok_moveable:
  1947.             output_token("MOVEABLE");
  1948.             break;
  1949.         case tok_discardable:
  1950.             output_token("DISCARDABLE");
  1951.             break;
  1952.         default:
  1953.             if (current_token_string() != NULL)
  1954.                 output_token (current_token_string ());
  1955.             done = 1;
  1956.             break;
  1957.         }
  1958.     }
  1959. }
  1960.  
  1961.  
  1962. /**************************************************************************
  1963.  *                                                                        *
  1964.  *  CONVERT_ACCELTABLE                                                    *
  1965.  *                                                                        *
  1966.  *  This procedure is called to convert an acceltable statement.          *
  1967.  *                                                                        *
  1968.  *  Syntax:                                                               *
  1969.  *      acctablename ACCELERATORS                                         *
  1970.  *      BEGIN                                                             *
  1971.  *          event, idvalue, [type] [NOINVERT] [ALT] [SHIFT] [CONTROL]     *
  1972.  *                                                                        *
  1973.  *                                                                        *
  1974.  **************************************************************************/
  1975.  
  1976. void convert_acceltable (void)
  1977. {
  1978. ushort      token;                          /* token type */
  1979. uchar   ptr string;
  1980. ushort        fControl = FALSE;
  1981.  
  1982. /*  Get the table identifier. */
  1983.  
  1984. get_token ();
  1985. output_token (current_token_string ());
  1986.  
  1987. /*  Output the ACCELERATOR and BEGIN keywords. */
  1988.  
  1989. output_token ("ACCELERATORS");
  1990. output_newline ();
  1991. output_token ("BEGIN");
  1992.  
  1993. /*
  1994.  *  Windows doesn't have any load options, so scan through any that might
  1995.  *  be associated with the OS/2 definition.
  1996.  */
  1997.  
  1998. while ((token = get_token ()) != tok_begin && token != tok_eof);
  1999.  
  2000. /*
  2001.  *  Until we've seen the END keyword or the EOF, output the information
  2002.  *  for each of the accelerators.
  2003.  */
  2004.  
  2005. while ((token = get_token ()) != tok_end && token != tok_eof) {
  2006.     /*
  2007.      *  Output the event.
  2008.      */
  2009.     output_newline ();
  2010.     output_tab (1);
  2011.     if (token == tok_numeric)
  2012.         output_value (current_token_value ());
  2013.     else {
  2014.         string = current_token_string ();
  2015.         if (token == tok_string) {
  2016.         if (*string == '^'){
  2017.         string_copy(string, string+1);
  2018.         fControl = TRUE;
  2019.         }
  2020.         else
  2021.         fControl = FALSE;
  2022.             convert_to_upper (string);
  2023.             output_string (string);
  2024.             }
  2025.         else if (equal_ignoring_case (string, "VK_BACKSPACE"))
  2026.             output_token ("VK_BACK");
  2027.         else
  2028.             output_token (string);
  2029.         }
  2030.     /*
  2031.      *  Output the comma.
  2032.      */
  2033.     token = get_token ();
  2034.     output_token (",");
  2035.     /*
  2036.      *  Output the idvalue.
  2037.      */
  2038.     token = get_token ();
  2039.     if (token == tok_numeric)
  2040.         output_value (current_token_value ());
  2041.     else
  2042.         output_token (current_token_string ());
  2043.  
  2044.     if ((token = get_token ()) == tok_plus) {
  2045.         output_token ("+");
  2046.         token = get_token ();
  2047.         output_value (current_token_value ());
  2048.         token = get_token ();
  2049.         }
  2050.     /*
  2051.      *  We want to make everything a virtual key, so output VERTKEY.
  2052.      */
  2053.     output_token (",");
  2054.     output_token ("VIRTKEY");
  2055.     /*
  2056.      *  While there are still commas, interpret the modifiers.
  2057.      */
  2058.     while (token == tok_comma) {
  2059.         /*
  2060.          *  Output the modifier.
  2061.          */
  2062.         token = get_token ();
  2063.         switch (token) {
  2064.             case tok_alt:
  2065.                 output_token (",");
  2066.                 output_token ("ALT");
  2067.                 break;
  2068.             case tok_char:
  2069.                 output_token (",");
  2070.                 output_token ("ASCII");
  2071.                 break;
  2072.             case tok_control:
  2073.                 output_token (",");
  2074.                 output_token ("CONTROL");
  2075.                 break;
  2076.             case tok_shift:
  2077.                 output_token (",");
  2078.                 output_token ("SHIFT");
  2079.                 break;
  2080.             case tok_virtualkey:
  2081.                 /*
  2082.                  *  Everything is already a virtual key, so don't ouput
  2083.                  *  anything.
  2084.                  */
  2085.                 break;
  2086.         case tok_syscommand:
  2087.         report_warning("Warning - SYSCOMMAND accels not supported.", token, current_token_string(), 0);
  2088.         break;
  2089.             default:
  2090.                 report_error (err_bad_accel_option, token, current_token_string ());
  2091.                 break;
  2092.             }
  2093.         token = get_token ();
  2094.         }
  2095.     if (fControl) {
  2096.     output_token (",");
  2097.     output_token ("CONTROL");
  2098.     fControl = FALSE;
  2099.     }
  2100.     put_token ();
  2101.     }
  2102.  
  2103. /*  Output the END keyword. */
  2104.  
  2105. output_newline ();
  2106. output_token ("END");
  2107. }
  2108.  
  2109.  
  2110. /**************************************************************************
  2111.  *                                                                        *
  2112.  *  CONVERT_RESOURCES                                                     *
  2113.  *                                                                        *
  2114.  *  This procedure is called to parse the OS/2 resource file and convert  *
  2115.  *  it into a Windows resource file.                                      *
  2116.  *                                                                        *
  2117.  **************************************************************************/
  2118.  
  2119. void convert_resources (void)
  2120. {
  2121. ushort      token;                          /* input token */
  2122.  
  2123. /*  While there are still input tokens, process them. */
  2124.  
  2125. while ((token = get_token ()) != tok_eof) {
  2126.     switch (token) {
  2127.         case tok_acceltable:
  2128.             output_newline ();
  2129.             convert_acceltable ();
  2130.             output_newline ();
  2131.             break;
  2132.  
  2133.         case tok_bitmap:
  2134.             convert_bitmap ();
  2135.             output_newline ();
  2136.             break;
  2137.  
  2138.         case tok_dlgtemplate:
  2139.             output_newline ();
  2140.             convert_dlgtemplate ();
  2141.             output_newline ();
  2142.             break;
  2143.  
  2144.         case tok_helptable:
  2145.             convert_helptable();
  2146.             break;
  2147.  
  2148.         case tok_helpsubtable:
  2149.             convert_helpsubtable();
  2150.             break;
  2151.  
  2152.         case tok_icon:
  2153.             convert_icon ();
  2154.             output_newline ();
  2155.             break;
  2156.  
  2157.         case tok_include:
  2158.             convert_include ();
  2159.             output_newline ();
  2160.             break;
  2161.  
  2162.         case tok_menu:
  2163.             output_newline ();
  2164.             convert_menu ();
  2165.             output_newline ();
  2166.             break;
  2167.  
  2168.         case tok_pointer:
  2169.             convert_pointer ();
  2170.             output_newline ();
  2171.             break;
  2172.  
  2173.         case tok_rcinclude:
  2174.             process_rcinclude ();
  2175.             output_newline ();
  2176.             break;
  2177.  
  2178.         case tok_resource:
  2179.             convert_resource ();
  2180.             output_newline ();
  2181.             break;
  2182.  
  2183.         case tok_stringtable:
  2184.             output_newline ();
  2185.             convert_stringtable ();
  2186.             output_newline ();
  2187.             break;
  2188.  
  2189.         case tok_dlginclude:
  2190.             process_dlginclude();
  2191.             break;
  2192.  
  2193.         default:
  2194.             report_error (err_convert_resources, token, current_token_string ());
  2195.             break;
  2196.         }
  2197.     }
  2198. }
  2199.  
  2200.  
  2201. /**************************************************************************
  2202.  *                                                                        *
  2203.  *  PROCESS_PARAMS                                                        *
  2204.  *                                                                        *
  2205.  *  This procedure is called to parse the parameter string and do         *
  2206.  *  the right thing.                                                      *
  2207.  *                                                                        *
  2208.  **************************************************************************/
  2209.  
  2210. flag process_params (int argc, char *argv [])
  2211. {
  2212. uchar   ptr src_fname;                      /* source filename */
  2213. uchar   ptr dst_fname;                      /* destination filename */
  2214.  
  2215. /*  Skip over our program name. */
  2216.  
  2217. argc--;
  2218. argv++;
  2219.  
  2220. //JMH Is there a debug flag?
  2221. if (*(*argv) == '-')
  2222.     {
  2223.     is_debug_on = TRUE;
  2224.     argc--;
  2225.     argv++;
  2226.     }
  2227.  
  2228. /*  We must have a source file name. */
  2229.  
  2230. if (argc < 1) {
  2231.     printf ("Incorrect usage: A source file name is required.\n");
  2232.     printf (usage_msg);
  2233.     return FALSE;
  2234.     }
  2235. src_fname = *argv++;
  2236. argc--;
  2237.  
  2238. /*  We must have a destination file name. */
  2239.  
  2240. if (argc < 1) {
  2241.     printf ("Incorrect usage: A destination file name is required.\n");
  2242.     printf (usage_msg);
  2243.     return FALSE;
  2244.     }
  2245. dst_fname = *argv++;
  2246. argc--;
  2247.  
  2248. /*  We should not have any more parameters. */
  2249.  
  2250. if (argc != 0) {
  2251.     printf ("Incorrect usage: Extra parameters found on command line\n");
  2252.     printf (usage_msg);
  2253.     return FALSE;
  2254.     }
  2255.  
  2256. /*  Open the source and destination files. */
  2257.  
  2258. if (cant open_source_file (src_fname) ||
  2259.     cant open_destination_file (dst_fname))
  2260.     return FALSE;
  2261.  
  2262. /*  Success. */
  2263.  
  2264. return TRUE;
  2265. }
  2266.  
  2267.  
  2268. /**************************************************************************
  2269.  *                                                                        *
  2270.  *  MAIN                                                                  *
  2271.  *                                                                        *
  2272.  *  This procedure is called by the system when the program is executed.  *
  2273.  *                                                                        *
  2274.  **************************************************************************/
  2275.  
  2276. void main (int argc, char *argv [])
  2277. {
  2278.  
  2279. /*  Do some initialization. */
  2280.  
  2281. //_asm int 03h  // put this line for debug break on entry
  2282. initialize_input ();
  2283.  
  2284. /*  Process the startup parameters and convert the resources. */
  2285.  
  2286.  
  2287. if (process_params (argc, argv))
  2288.     convert_resources ();
  2289.  
  2290. /*  Do some cleanup. */
  2291.  
  2292. close_destination_file ();
  2293. terminate_input ();
  2294. }
  2295.